package com.xci.core.helper;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.servlet.ServletUtil;
import com.xci.core.internal.Const;
import com.xci.core.internal.Sys;
import com.xci.sys.entity.SysDic;
import com.xci.sys.entity.SysUser;
import org.springframework.stereotype.Component;
import org.springframework.ui.ModelMap;
import org.springframework.web.servlet.support.RequestContext;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.NotNull;
import javax.xml.datatype.XMLGregorianCalendar;
import java.io.File;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 页面帮助类
 * @author 吕艳阳
 */
@Component
public class HtmlHelper {
    @Resource
    private HttpServletRequest httpServletRequest;

    /**
     * 标记新建记录
     * @param map 模型对象
     */
    public void createMark(ModelMap map) {
        Helper.createMark(map);
    }

    /**
     * 是否新建记录
     */
    public boolean isCreate() {
        return Helper.isCreate();
    }

    /**
     * 获取站点Url信息
     */
    public String getSiteUrl() {
        return WebHelper.getSiteUrl();
    }

    /**
     * 获取当前日期时间对象
     */
    public Date now() {
        return new Date();
    }

    /**
     * 格式化日期(默认格式yyyy-MM-dd)
     * @param date 指定的时间
     * @return 返回日期格式化后的字符串
     */
    public String formatDate(Date date) {
        return DateHelper.formatDate(date);
    }

    /**
     * 格式化日期(默认格式yyyy-MM-dd)
     * added by yao 2018-12-15
     * @param date 指定的时间(XMLGregorianCalendar)
     * @return 返回日期格式化后的字符串
     */
    public String formatCalendarDate(XMLGregorianCalendar date) {
        if (date == null) {
            return "";
        }
        return DateHelper.formatDate(date.toGregorianCalendar().getTime());
    }

    /**
     * 格式化日期字符串(默认格式 yyyy-MM-dd HH:mm)
     * @param date 指定的时间
     * @return 返回日期格式化后的字符串
     */
    public String formatDateHasMinute(Date date) {
        return DateHelper.formatDateHasMinute(date);
    }

    /**
     * 格式化日期(默认格式 yyyy-MM-dd HH:mm:ss)
     * @param date 指定的时间
     * @return 返回日期格式化后的字符串
     */
    public String formatDateTime(Date date) {
        return DateHelper.formatDateTime(date);
    }

    /**
     * 格式化日期
     * @param date 指定的时间(XMLGregorianCalendar)
     * @return 返回日期格式化后的字符串
     */
    public String formatXmlDate(XMLGregorianCalendar date, String format) {
        if (date == null) {
            return "";
        }
        return DateHelper.format(date.toGregorianCalendar().getTime(), format);
    }

    /**
     * 格式化日期(默认格式 yyyy-MM-dd HH:mm:ss)
     * added by yao 2018-12-15
     * @param date 指定的时间(XMLGregorianCalendar)
     * @return 返回日期格式化后的字符串
     */
    public String formatCalendarDateTime(XMLGregorianCalendar date) {
        if (date == null) {
            return "";
        }
        return DateHelper.formatDateTime(date.toGregorianCalendar().getTime());
    }

    /**
     * 格式化日期(默认格式 yyyy-MM-dd HH:mm:ss)
     * added by yao 2018-12-15
     * @param date 指定的时间(XMLGregorianCalendar)
     * @return 返回日期格式化后的字符串
     */
    public String formatCalendarDateTimeToDefaultDatePattern(XMLGregorianCalendar date) {
        if (date == null) {
            return "";
        }
        return DateHelper.format(date.toGregorianCalendar().getTime(), Const.DEFAULT_DATE_PATTERN);
    }

    /**
     * 获取格式化的时间字符串(默认格式 HH:mm:ss)
     * @param date 指定的时间
     * @return 返回日期格式化后的字符串
     */
    public String formatTime(Date date) {
        return DateHelper.formatTime(date);
    }

    /**
     * 格式化日期
     * @param date   指定的时间
     * @param format 格式字符串
     * @return 返回日期格式化后的字符串
     */
    public String formatDate(Date date, String format) {
        return DateHelper.format(date, format);
    }

    /**
     * 以 conjunction 为分隔符将多个对象转换为字符串
     * @param conjunction 分隔符
     * @param objs        数组
     * @return 连接后的字符串
     * @see ArrayUtil#join(Object, CharSequence)
     */
    public String join(CharSequence conjunction, Object... objs) {
        return ArrayUtil.join(objs, conjunction);
    }

    public boolean contains(String source, String sub) {
        return source.toLowerCase().contains(sub.toLowerCase());
    }

    /**
     * 字符串是否为空白 空白的定义如下： <br>
     * 1、为null <br>
     * 2、为不可见字符（如空格）<br>
     * 3、""<br>
     * @param str 被检测的字符串
     * @return 是否为空
     */
    public boolean isBlank(CharSequence str) {
        return StrUtil.isBlank(str);
    }

    /**
     * 字符串是否为非空白 空白的定义如下： <br>
     * 1、不为null <br>
     * 2、不为不可见字符（如空格）<br>
     * 3、不为""<br>
     * @param str 被检测的字符串
     * @return 是否为非空
     */
    public boolean isNotBlank(CharSequence str) {
        return !isBlank(str);
    }

    /**
     * 获取Web项目下的web root路径
     * @return web root路径
     * @since 4.0.13
     */
    public static File getWebRoot() {
        return FileUtil.getWebRoot();
    }

    /**
     * 获得文件的扩展名，扩展名不带“.”
     * @param fileName 文件名
     * @return 扩展名
     */
    public static String extName(String fileName) {
        return FileUtil.extName(fileName);
    }

    /**
     * 返回主文件名
     * @param fileName 完整文件名
     * @return 主文件名
     */
    public static String mainName(String fileName) {
        return FileUtil.mainName(fileName);
    }

    /**
     * json序列化
     * @param data 待序列化的对象
     */
    public static String jsonSerialize(Object data) {
        return JsonHelper.serialize(data);
    }

    /**
     * json 反序列化
     * @param json json 字符串
     * @return 返回序列化的对象
     */
    public static Object jsonDeserialize(String json) {
        return JsonHelper.deserialize(json, Object.class);
    }

    /**
     * 是否有指定模块编码的权限
     * @param codes 模块编码字符串
     */
    public boolean isAuthorize(String codes) {
        return Sys.me().isAuthorize(Sys.me().getCurrentUser(), codes);
    }

    /**
     * 根据参数编码获取参数值
     * @param code 参数编码
     * @return 返回参数编码对应的参数值, 如果找不到指定的参数则返回空字符串
     */
    public String getParamValue(@NotNull String code) {
        return getParamValue(code, Const.EMPTY);
    }

    /**
     * 根据参数编码获取参数值
     * @param code         参数编码
     * @param defaultValue 找不到参数时返回的默认值
     * @return 返回参数编码对应的参数值
     */
    public String getParamValue(@NotNull String code, String defaultValue) {
        return Sys.me().getParamValue(code, defaultValue);
    }

    /**
     * 根据字典编码获取字典明细列表
     * @param dicCode 字典编码
     */
    public List<SysDic> getDicList(String dicCode) {
        return Sys.me().getDicList(dicCode);
    }

    /**
     * 获取客户端IP
     * @return IP地址
     */
    public String getClientIP() {
        var request = WebHelper.getRequest();
        return ServletUtil.getClientIP(request);
    }

    /**
     * 获取请求上下文
     * @return 返回请求上下文
     */
    public String getContextPath() {
        return WebHelper.getRequest().getContextPath();
    }

    /**
     * 获取请求上下文绝对路径
     * @param relativeUrl 指定的路径
     * @return 返回请求上下文绝对路径
     */
    public String getContextUrl(String relativeUrl) {
        return WebHelper.getContextUrl(httpServletRequest, relativeUrl);
    }

    /**
     * 获取请求上下文绝对路径
     * @param relativeUrl 指定的路径
     * @param params      传递的参数
     * @return 返回请求上下文绝对路径
     */
    public String getContextUrl(String relativeUrl, Map<String, ?> params) {
        return WebHelper.getContextUrl(httpServletRequest, relativeUrl, params);
    }

    /**
     * 获取当前操作用户
     */
    public SysUser getCurrentUser(){
        return Sys.me().getCurrentUser();
    }
}